﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using PloobsEngine;
using PloobsEngine.Cameras;
using PloobsEngine.Commands;
using PloobsEngine.Features;
using PloobsEngine.Input;
using PloobsEngine.Light;
using PloobsEngine.Material;
using PloobsEngine.Modelo;
using PloobsEngine.Physics;
using PloobsEngine.Physics.Bepu;
using PloobsEngine.SceneControl;
using PloobsEngineDemo3;
using PloobsEngine.Utils;

namespace Etapa1.Screens
{
    /// <summary>
    /// Transparencia Screen
    /// </summary>
    public class TransparentScreen : SceneScreen
    {
        private BepuPhysicWorld physicWorld;
        private BrutalForceWorld mundo;
        private EngineStuff engine;        
        ICamera cam;        

        public TransparentScreen(EngineStuff es)
        {
            this.engine = es;
            physicWorld = new BepuPhysicWorld();
            mundo = new BrutalForceWorld(physicWorld);                                    
        }
        
        public override void LoadContent(EngineStuff es)
        {            
            InputAdvanced inp = new InputAdvanced(engine);
            engine.AddComponent(inp);

            base.LoadContent(es);            

            ///Cubo Opaco normal
            #region Models
            {
                ///Cria um modelo (NAO PASSA A TEXTURA A SER UTILIZADA)
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\cubo");
                ///cria uma textura proceduralmente e seta como diffuse (cor do modelo) - tamanho 1x1
                sm.SetTexture(TextureCreator.CreateColorTexture(1, Color.White), TextureType.DIFFUSE);
                sm.LoadModelo();
                BoxObject pi = new BoxObject(new Vector3(100, 20, 0), 1, 5,new Vector3(100, 5, 100));                
                CustomDeferred shader = new CustomDeferred(false, false, false, false);
                shader.SpecularIntensity = 0;
                shader.SpecularPower = 0;
                shader.Initialize();
                IMaterial mat = new Material(shader);
                IObject obj3 = new SimpleObject(mat, pi, sm);
                mundo.AddObject(obj3);
            }

            ///Idem - outra cor
            {
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\cubo");
                sm.SetTexture(TextureCreator.CreateColorTexture(256, Color.Blue), TextureType.DIFFUSE);
                sm.LoadModelo();
                BoxObject pi = new BoxObject(new Vector3(90, 30, 0), 1, 10,new Vector3(1));                
                CustomDeferred shader = new CustomDeferred(false, false, false, false);
                shader.SpecularIntensity = 0;
                shader.SpecularPower = 0;
                shader.Initialize();
                IMaterial mat = new Material(shader);
                IObject obj3 = new SimpleObject(mat, pi, sm);
                mundo.AddObject(obj3);
            }

            ///Cenario classico
            {
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\cenario");
                sm.LoadModelo();
                IPhysicObject pi = new TriangleMeshObject(Vector3.Zero, sm);                
                CustomDeferred shader = new CustomDeferred(false, false, false, false);
                shader.SpecularIntensity = 0;
                shader.SpecularPower = 0;
                shader.Initialize();
                IMaterial mat = new Material(shader);
                IObject obj3 = new SimpleObject(mat, pi, sm);
                mundo.AddObject(obj3);
            }

            ///Varios blocos transparentes
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    ///Cria modelo com textura procedural amarela
                    SimpleModel sm = new SimpleModel("..\\Content\\Model\\block");
                    sm.SetTexture(TextureCreator.CreateColorTexture(1, Color.Yellow), TextureType.DIFFUSE);
                    sm.LoadModelo();                    
                    ///Objeto fisico Ghost (nao tem colisao, nem formato)
                    GhostObject pi = new GhostObject(new Vector3(i * 10, 50, j * 10), Matrix.Identity, new Vector3(5));
                    pi.isMotionLess = true;
                    ///Cria o shader de transparencia                    
                    ///Caso a textura do modelo nao tenha Alpha, ela pode ser setada usando shader.TransparencyLevel
                    ///OBJETOS TRANSPARENTES NAO SAO AFETADOS PELA LUZ, a sua cor final sera uma combinacao entre a textura difuse e o efeito de transparencia
                    ///O shader de transparencia eh aplicado no passo Forward
                    TransparenteNormal shader = new TransparenteNormal();                                        
                    shader.Initialize();
                    shader.TransparencyLevel = 0.7f;
                    IMaterial mat = new Material(shader);
                    IObject obj4 = new SimpleObject(mat, pi, sm);
                    mundo.AddObject(obj4);
                }

            }

            ///Cubos opacos
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    IModelo sm = new SimpleModel("..\\Content\\Model\\block", "..\\Content\\Textures\\blue");
                    sm.LoadModelo();
                    ///Objeto fisico Ghost (nao tem colisao)
                    GhostObject pi = new GhostObject(new Vector3( i * 10, 100, j * 10), Matrix.Identity, new Vector3(5));
                    pi.isMotionLess = true;
                    CustomDeferred shader = new CustomDeferred(false, false, false, false);
                    shader.Initialize();                    
                    IMaterial mat = new Material(shader);
                    IObject obj4 = new SimpleObject(mat, pi, sm);
                    mundo.AddObject(obj4);
                }

            }

            #endregion            

            cam = new CameraFirstPerson(true);            
            cam.FarPlane = 3000;

            LightThrowBepu lt = new LightThrowBepu(mundo, engine);         

            #region NormalLight
            DirectionalLight ld1 = new DirectionalLight(Vector3.Left, Color.White);
            DirectionalLight ld2 = new DirectionalLight(Vector3.Right, Color.White);
            DirectionalLight ld3 = new DirectionalLight(Vector3.Backward, Color.White);
            DirectionalLight ld4 = new DirectionalLight(Vector3.Forward, Color.White);
            DirectionalLight ld5 = new DirectionalLight(Vector3.Down, Color.White);
            float li = 0.4f;
            ld1.LightIntensity = li;
            ld2.LightIntensity = li;
            ld3.LightIntensity = li;
            ld4.LightIntensity = li;
            ld5.LightIntensity = li;
            mundo.AddLight(ld1);
            mundo.AddLight(ld2);
            mundo.AddLight(ld3);
            mundo.AddLight(ld4);
            mundo.AddLight(ld5);
            #endregion

            ////Criacao de uma Tecnica
            DeferredRenderTechnic dr = new DeferredRenderTechnic(engine);
            
            IRenderTechnic[] rt = new IRenderTechnic[] { dr };
            this.RenderTechnics = rt;
            mundo.AddCamera(cam);
            this.World = mundo;
        }        
    }
}

